package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/config"
	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/common"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/integration"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/hlPay"
	"gitee.com/wangshh_123/cross-pay-go/src/platform/providers/photonpay"
	"gitee.com/wangshh_123/cross-pay-go/src/router"
	utils "gitee.com/wangshh_123/cross-pay-go/src/utils/common"

	"gitee.com/wangshh_123/cross-pay-go/src/utils/websocket"
	"github.com/gin-gonic/gin"
)

// Version 应用程序版本号
var Version = "dev"

// 自定义日志中间件
func customLogger() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 开始时间
		start := time.Now()
		path := c.Request.URL.Path

		// 处理请求
		c.Next()

		// 结束时间
		end := time.Now()
		latency := end.Sub(start)

		// 只在发生错误时记录日志
		if c.Writer.Status() >= 400 {
			fmt.Printf("[GIN] %v | %3d | %13v | %15s | %s %s\n",
				end.Format("2006/01/02 - 15:04:05"),
				c.Writer.Status(),
				latency,
				c.ClientIP(),
				c.Request.Method,
				path,
			)
		}
	}
}

func main() {
	// 设置日志前缀
	log.SetPrefix("[cross-pay-go] ")
	log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile)

	// 创建上下文，用于优雅关闭
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
	defer stop()

	// 启动内存监控
	utils.StartMemoryMonitor(30 * time.Second)
	utils.MonitorGoroutines(1000) // 设置goroutine数量阈值为1000

	// 初始化配置
	if err := config.Init(); err != nil {
		log.Fatalf("Failed to initialize config: %v", err)
	}
	log.Printf("Starting cross-pay-go version %s", Version)
	log.Println("Configuration loaded successfully")

	// 初始化时区配置
	timezoneConfig := &utils.TimeZoneConfig{
		DefaultTimeZone:  config.GlobalConfig.TimeZone.DefaultTimeZone,
		DatabaseTimeZone: config.GlobalConfig.TimeZone.DatabaseTimeZone,
		DisplayTimeZone:  config.GlobalConfig.TimeZone.DisplayTimeZone,
	}
	if err := utils.InitTimeZone(timezoneConfig); err != nil {
		log.Fatalf("Failed to initialize timezone config: %v", err)
	}
	log.Printf("Timezone initialized - Default: %s, Database: %s, Display: %s",
		timezoneConfig.DefaultTimeZone, timezoneConfig.DatabaseTimeZone, timezoneConfig.DisplayTimeZone)

	// 设置 Gin 模式
	gin.SetMode(config.GlobalConfig.Server.Mode)

	// 创建 Gin 引擎
	r := gin.New()

	// 使用自定义的日志中间件
	r.Use(gin.Recovery())
	r.Use(customLogger())

	// 初始化数据库连接
	if err := database.Init(); err != nil {
		log.Fatalf("Failed to initialize database: %v", err)
	}

	// 初始化 Redis 连接
	if err := database.InitRedis(); err != nil {
		log.Fatalf("Failed to initialize Redis: %v", err)
	}

	// 初始化 MongoDB 连接
	if err := database.InitMongoDB(); err != nil {
		log.Fatalf("Failed to initialize MongoDB: %v", err)
	}

	// 初始化平台工厂
	if err := integration.InitializeAllGlobalPlatforms(); err != nil {
		log.Fatalf("Failed to initialize platform factory: %v", err)
	}
	log.Println("Platform factory initialized successfully")

	// 初始化PhotonPay客户端
	photonPayClient := photonpay.GetPhotonPayClient(&common.PlatformConfig{
		GatewayURL: config.GlobalConfig.PhotonPay.GatewayURL,
	})

	// 初始化HlPay客户端
	hlPayClient := hlPay.GetHlPayClient(&hlPay.HlPayConfig{
		ClientID:       config.GlobalConfig.HlPay.ClientID,
		ClientKey:      config.GlobalConfig.HlPay.ClientKey,
		ClientSecret:   config.GlobalConfig.HlPay.ClientSecret,
		GatewayURL:     config.GlobalConfig.HlPay.GatewayURL,
		RefreshTime:    config.GlobalConfig.HlPay.RefreshTime,
		MinRefreshTime: config.GlobalConfig.HlPay.MinRefreshTime,
	})

	// 确保全局平台管理器使用正确的客户端
	globalManager := integration.GetGlobalPlatformManager()
	if globalManager == nil {
		log.Fatalf("Global platform manager is nil")
	}

	// 验证平台是否已注册
	supportedPlatforms := globalManager.GetFactory().GetSupportedPlatforms()
	log.Printf("Supported platforms: %v", supportedPlatforms)

	// 初始化路由，传递客户端实例
	router.SetupRouter(r, photonPayClient, nil, hlPayClient)
	log.Println("Router setup completed")

	// 优雅关闭
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		port := fmt.Sprintf(":%d", config.GlobalConfig.Server.Port)
		if err := r.Run(port); err != nil {
			log.Fatalf("启动服务器失败: %v", err)
		}
	}()

	// 启动 WebSocket Hub
	go func() {
		log.Println("WebSocket Hub started")
		websocket.GlobalHub.Run()
	}()

	// 等待中断信号
	<-ctx.Done()
	log.Println("正在关闭服务器...")

	// 关闭数据库连接
	if err := database.Close(); err != nil {
		log.Printf("关闭数据库连接失败: %v", err)
	}

	// 关闭 Redis 连接
	if err := database.CloseRedis(); err != nil {
		log.Printf("Error closing Redis connection: %v", err)
	}

	// 关闭 MongoDB 连接
	if err := database.CloseMongoDB(); err != nil {
		log.Printf("Error closing MongoDB connection: %v", err)
	}

	// 等待所有连接处理完成
	<-ctx.Done()
	log.Println("服务器已关闭")
}

// recoverPanic 恢复 panic
func recoverPanic() {
	if r := recover(); r != nil {
		log.Printf("Recovered from panic: %v", r)
		// 这里可以添加告警通知等逻辑
	}
}
